<template>
    <Form :model="selectedStep" layout="vertical">
        <Form.Item label="名称：" :class="{'custom-label': differentFields.includes('name')}">
            <Input v-model:value="selectedStep.name" :disabled="operatorDisabled"/>
        </Form.Item>

        <Form.Item label="操作类型：" :class="{'custom-label': differentFields.includes('operationType')}">
            <Cascader v-model:value="currentSelectedOptions" :options="cascaderOptions" placeholder="请选择操作类型"
                :show-search="{ filter }" :display-render="({ labels }) => labels[labels.length - 1]" @change="(value) => {
                    value[value.length - 1] &&
                        (selectedStep.operationType = value[
                            value.length - 1
                        ] as string)
                }
                    " :disabled="operatorDisabled" />
        </Form.Item>

        <Form.Item v-for="(item, index) in currentSelectedValue" :key="index" :label="item.name" :class="{'custom-label': item.field === 'locationType' && differentFields.includes('locationType') || item.field === 'locationExpress' && differentFields.includes('locationExpress') || item.field === 'value' && differentFields.includes('value') || item.field === 'saveKey' && differentFields.includes('saveKey') || item.field === 'elementWait' && differentFields.includes('elementWait') || item.field === 'expectValue' && differentFields.includes('expectValue')}">
            <div v-if="item.field.toLowerCase().includes('locationtype')">
                <!-- @vue-expect-error -->
                <Select v-model:value="/* @ts-ignore */ selectedStep[item.field]" :options="data?.ui_location_type.map((item) => ({
                    label: item.name,
                    value: item.value,
                }))
                    " :disabled="operatorDisabled"/>
            </div>
            <Input v-else v-model:value="/* @ts-ignore */ selectedStep[item.field]" :placeholder="`请输入${item.name}`" :disabled="operatorDisabled"/>
        </Form.Item>

        <Form.Item label="引擎类型：" :class="{'custom-label': differentFields.includes('engineType')}">
            <Input v-model:value="selectedStep.engineType" disabled />
        </Form.Item>

        <Form.Item label="重试类型：" :class="{'custom-label': differentFields.includes('retryType')}">
            <Select v-model:value="selectedStep.retryType" :disabled="true">
                <Select.Option value="同步">同步重试</Select.Option>
                <Select.Option value="异步">异步重试</Select.Option>
            </Select>
        </Form.Item>

        <Form.Item label="重试次数：" :class="{'custom-label': differentFields.includes('retryCount')}">
            <InputNumber v-model:value="selectedStep.retryCount" :disabled="isRetrySwitchType || operatorDisabled" />
        </Form.Item>

        <Form.Item label="首次重试间隔(单位: 秒 )：" :class="{'custom-label': differentFields.includes('retryFirstInterval')}">
            <InputNumber v-model:value="selectedStep.retryFirstInterval" :disabled="isRetrySwitchType || operatorDisabled"/>
        </Form.Item>

        <div flex="~ justify-around">
            <Form.Item label="是否截图：" :class="{'custom-label': differentFields.includes('isScreenshot')}">
                <Switch v-model:checked="selectedStep.isScreenshot" :disabled="operatorDisabled"/>
            </Form.Item>

            <Form.Item label="失败是否继续：" :class="{'custom-label': differentFields.includes('isContinue')}"> 
                <Switch v-model:checked="selectedStep.isContinue" :disabled="operatorDisabled"/>
            </Form.Item>

            <Form.Item label="失败是否重试(默认关闭)：" :class="{'custom-label': differentFields.includes('isRetry')}">
                <Switch v-model:checked="selectedStep.isRetry" :disabled="operatorDisabled"/>
            </Form.Item>
        </div>
    </Form>
</template>

<script setup lang="ts">
import { Cascader, Form, Input, InputNumber, Select, Switch } from 'ant-design-vue'
import { objectOmit } from '@vueuse/core'
import {
    type IUICaseStep,
} from '../../types/apis/ui-case'
import type {
    CascaderProps,
    ShowSearchType,
} from 'ant-design-vue/es/vc-cascader'
import { watch, ref, reactive, computed } from 'vue'

const props = defineProps({
    databaseConstantSelectOptions: {} as IDatabaseConstantSelectOptions,
    apiConstantSelectOptions: {} as IUIConstantSelectOptions,
    data: [] as IUICaseStep[],
    operatorDisabled: {
        type: Boolean,
        default: false
    },
    differentFields: {
        type: Array,
        default: []
    }
})
const selectedStep = defineModel<IUICaseStep>('selectedStep', {
    required: true,
})

const globalConfig = useGlobalConfigStore()

const currentSelectedOptions = ref<string[]>([])

watch(() => globalConfig.selectedStep,
    (newValue) => {
        initOperationType(newValue.operationType)
    },
    { deep: true }
)


watch(
    selectedStep,
    async () => {
        initOperationType(selectedStep.value?.operationType)
        await deserialize()
    },
    { deep: true, immediate: true },
) 


/**
 * 重试开关变动
 */
let isRetrySwitchType = ref(!globalConfig.selectedStep.isRetry);
watch(() => globalConfig.selectedStep.isRetry,
    (newValue) => {
        if (newValue) {
            isRetrySwitchType.value = false
        } else {
            isRetrySwitchType.value = true
        }
    },
    { deep: true }
)

const currentSelectedValue = computed(() => {
    const category = props.data?.[currentSelectedOptions.value?.[0] as keyof ResponseType]
    if (!category) {
        return []
    }
    const selected = category.find(
        (item) => item.value === currentSelectedOptions.value?.[1],
    )
    return selected
        ? objectDeserializer<{ name: string; field: string }>(selected.extend, true)
        : []
})


const cascaderOptions = computed(() => {
    console.log('props.data-->', props.data)
    if (!props.data) {
        return []
    }

    return Object.entries(
        objectOmit(props.data, ['ui_location_type', 'browser_type']),
    )
        .filter(([, value]) => value.length > 0)
        .map(([key, value]) => ({
            value: key,
            label: value?.[0]?.categoryName ?? '',
            children: value.map((item) => ({
                value: item.value,
                label: item.name,
            })),
        })) as CascaderProps['options']
})

watch(() => cascaderOptions, () => {
    if(Object.keys(cascaderOptions).length > 0){
            initOperationType(selectedStep.value?.operationType)
        }
}, {
    deep: true,
    immediate: true,
})

const filter: ShowSearchType['filter'] = (inputValue, path) => {
    return path.some((option) =>
        option.label.toLowerCase().includes(inputValue.toLowerCase()),
    )
}
function initOperationType(type: string | undefined) {
    if (!type) return
    const found = cascaderOptions.value?.find(
        (item) => item.children?.find((child) => child.value === type) != null,
    )

    if (!found) return

    currentSelectedOptions.value = [
        found.value as string,
        found.children!.find((child) => child.value === type)!.value as string,
    ]

}

function serialize() {
}

async function deserialize() {

}

defineExpose({ serialize })

</script>

<style scoped>
:deep(.custom-label .ant-form-item-label label) {
  color: red !important;
}
</style>